package com.java.product.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.java.clients.*;
import com.java.param.*;
import com.java.pojo.Category;
import com.java.pojo.Picture;
import com.java.pojo.Product;
import com.java.product.mapper.PictureMapper;
import com.java.product.mapper.ProductMapper;
import com.java.product.service.ProductService;
import com.java.to.OrderToProduct;
import com.java.utils.R;
import com.sun.javafx.font.LogicalFont;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

@Service
@Slf4j
public class ProductServiceImpl extends ServiceImpl<ProductMapper,Product> implements ProductService {

    @Autowired
    private ProductMapper productMapper;
    //引入feign客户端，需要在启动类添加配置注解
    @Autowired
    private CategoryClient categoryClient;
    @Autowired
    private PictureMapper pictureMapper;
    @Autowired
    private SearchClient searchClient;
    @Autowired
    private CartClient cartClient;
    @Autowired
    private OrderClient orderClient;
    @Autowired
    private CollectClient collectClient;

    /**
     *
     * 单类别名称，查询热门商品，最多7条数据
     * 1.根据类别名称，调用feign客户端访问类别服务，获取类别数据
     * 2.成功，根据类别id查询商品数据（销售量，热门，查询7条）
     * 3.封装结果
     * @param categoryName 类别名称
     * @return 7条数据
     */
    @Override
    @Cacheable(value = "list.product",key = "#categoryName",cacheManager = "cacheManagerHour")
    public R promo(String categoryName) {
        R r = categoryClient.byName(categoryName);
        if (r.getCode().equals(R.FAIL_CODE)) {
            log.info("ProductServiceImpl.promo 业务已经完成,结果:{}", "类别查询失败");
            return r;
        }
        //类别服务中 data = category 在调用feign{json}到product服务转换成了LinkedHashMap
        LinkedHashMap<String,Object> map = (LinkedHashMap<String, Object>) r.getData();
        Integer categoryId = (Integer) map.get("category_id");
        //封装数据，查询
        QueryWrapper<Product> queryWrapper =new QueryWrapper<>();
        queryWrapper.eq("category_id",categoryId);
        queryWrapper.orderByDesc("product_sales");

        //分页,第几页，每页多少
        IPage<Product> page = new Page<>(1,7);
        //返回的是包装数据，内部有对应的商品集合，也有分页参数，如总条数，总页数等
        page = productMapper.selectPage(page, queryWrapper);
        List<Product> productList = page.getRecords();//获取指定页数据
        long total = page.getTotal();//获取总数量

        log.info("ProductServiceImpl.promo 业务已经完成,结果:{}", productList);
        return R.ok("数据查询成功",productList);
    }

    /**
     * 根据类别集合，获取商品信息
     *
     * @param productHotParam
     * @return
     */
    @Override
    @Cacheable(value="list.product",key = "#productHotParam.categoryName")
    public R hots(ProductHotParam productHotParam) {

        R hots = categoryClient.hots(productHotParam);
        if(hots.getCode().equals(R.FAIL_CODE)){
            log.info("ProductServiceImpl.hots 业务已经完成,结果:{}","多类别热门查询失败");
            return hots;
        }
        List<Object> ids = (List<Object>) hots.getData();
        QueryWrapper<Product> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("category_id",ids);
        queryWrapper.orderByDesc("product_sales");
        IPage<Product> page = new Page<>(1,7);
        page = productMapper.selectPage(page, queryWrapper);
        List<Product> records = page.getRecords();
        log.info("ProductServiceImpl.hots 业务已经完成,结果:{}","多类别热门查询成功");
        return R.ok("多类别热门查询成功！",records);
    }

    /**
     * 获取全部商品类别信息
     *
     * @return
     */
    @Override
    @Cacheable(value = "list.category",key = "#root.methodName",cacheManager = "cacheManagerDay")
    public R cList() {
        R list = categoryClient.list();
        if(list.getCode().equals(R.FAIL_CODE)){
            log.info("ProductServiceImpl.list 业务已经完成,结果:{}", "全部类别信息查询失败");
            return R.fail("全部类别信息查询失败！");
        }
        return R.ok("全部类别信息查询成功！",list.getData());
    }

    /**
     * 根据类别id，页数，页码，查询商品数据
     *
     * @param productIdsParam
     * @return 商品数据，总数量
     */
    @Override
    @Cacheable(value = "list.product",key = "#productIdsParam.categoryID+'-'+#productIdsParam.currentPage+'-'+#productIdsParam.pageSize")
    public R byCategory(ProductIdsParam productIdsParam) {
        //封装查询数据
        QueryWrapper<Product> queryWrapper = new QueryWrapper<>();
        //拆分数据，便于复用查询全部商品信息
        List<Integer> categoryID = productIdsParam.getCategoryID();
        if(categoryID!=null&&categoryID.size()>0){
            queryWrapper.in("category_id",productIdsParam.getCategoryID());
        }
        //设置查询页码信息
        IPage<Product> page = new Page<>(productIdsParam.getCurrentPage(),productIdsParam.getPageSize());

        page = productMapper.selectPage(page,queryWrapper);
        long total = page.getTotal();
        List<Product> records = page.getRecords();
        //封装结果
        R ok = R.ok("商品信息查询成功！", records, total);
        return ok;
    }

    /**
     * 根据商品id，查询商品详细信息
     *
     * @param productIdParam
     * @return
     */
    @Override
    @Cacheable(value = "product",key = "#productIdParam.productID")
    public R detail(ProductIdParam productIdParam) {
        QueryWrapper<Product> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("product_id",productIdParam.getProductID());
        Product product = productMapper.selectOne(queryWrapper);
        if(product==null){
            log.info("ProductServiceImpl.detail 业务已经完成,结果:{}", "商品详细信息查询失败");
            return R.fail("商品详细信息查询失败！");
        }
        log.info("ProductServiceImpl.detail 业务已经完成,结果:{}", product);
        return R.ok("商品详细查询成功！",product);
    }

    /**
     * 搜素服务调用，获取全部商品用于搜索数据库同步
     *
     * @return
     */
    @Override
    public List<Product> allList() {
        List<Product> products = productMapper.selectList(null);
        log.info("ProductServiceImpl.allList 业务已经完成,结果:{}", products);
        return products;
    }

    /**
     * 根据商品id，查询商品全部图片信息
     *
     * @param productIdParam
     * @return
     */
    @Override
    @Cacheable(value = "picture",key = "#productIdParam.productID")
    public R pictures(ProductIdParam productIdParam) {
        QueryWrapper<Picture> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("product_id",productIdParam.getProductID());
        List<Picture> pictures = pictureMapper.selectList(queryWrapper);
        if(pictures==null){
            log.info("ProductServiceImpl.detail 业务已经完成,结果:{}", "商品图片信息查询失败");
            return R.fail("商品图片信息查询失败！");
        }
        log.info("ProductServiceImpl.detail 业务已经完成,结果:{}", pictures);
        return R.ok("商品图片信息查询成功！",pictures);
    }



    /**
     * 搜索服务调用
     *
     * @param productSearchParam
     * @return
     */
    @Override
    public R search(ProductSearchParam productSearchParam) {
        R search = searchClient.search(productSearchParam);
        log.info("ProductServiceImpl.search 业务已经完成,结果:{}", search);
        return search;
    }

    /**
     * 根据商品id集合查询商品信息
     *
     * @param productIds
     * @return
     */
    @Cacheable(value = "list.product",key = "#productIds")
    @Override
    public R Ids(List<Integer> productIds) {

        QueryWrapper<Product> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("product_id",productIds);
        List<Product> productList = productMapper.selectList(queryWrapper);

        log.info("ProductServiceImpl.Ids 业务已经完成,结果:{}", productIds);
        
        return R.ok("类别信息查询成功！",productList);
    }

    /**
     * 修改库存，增加销售量
     *
     * @param orderToProducts
     */
    @Override
    public void subNumber(List<OrderToProduct> orderToProducts) {
        //将集合转成map ,productId-key ,orderToProduct-value
        Map<Integer, OrderToProduct> map = orderToProducts.stream().collect(Collectors.toMap(OrderToProduct::getProductId, v -> v));
        //获取商品集合id
        Set<Integer> productIds = map.keySet();
        //查询集合对应的商品信息
        List<Product> products = productMapper.selectBatchIds(productIds);
        //修改商品信息
        for (Product product : products) {
            Integer num = map.get(product.getProductId()).getNum();
            product.setProductNum(product.getProductNum()-num);
            product.setProductSales(product.getProductSales()+num);
        }
        //批量更新
        this.updateBatchById(products);
        log.info("ProductServiceImpl.subNumber 业务已经完成,结果:库存和销售量修改完毕！");
    }

    /**
     * 保存商品和图片信息
     *
     * @param adminProductParam
     * @return
     */
    @CacheEvict(value = "list.product",allEntries = true)
    @Override
    public R adminSave(AdminProductParam adminProductParam) {

        Product product = new Product();
        BeanUtils.copyProperties(adminProductParam,product);
        int rows = productMapper.insert(product);
        if(rows==0){
            return R.fail("商品添加失败！");
        }
        String pictures = adminProductParam.getPictures();
        if (!StringUtils.isEmpty(pictures)) {
            //截取特殊字符串的时候\\ []包含$ + | ?
            String[] split = pictures.split("\\+");
            for (String s : split) {
                Picture picture = new Picture();
                picture.setIntro(null);
                picture.setProductId(product.getProductId());
                picture.setProductPicture(s);
                pictureMapper.insert(picture);
            }
        }

//保存成功，同步商品，将商品插入到es库
        searchClient.saveOrUpdate(product);
        return R.ok("商品数据添加成功！");


    }

    /**
     * 更新商品信息
     *
     * @param product
     * @return
     */
    //@CacheEvict(value = "list.product",allEntries = true )
    @Override
    public R adminUpdate(Product product) {
        int rows = productMapper.updateById(product);
        if(rows==0){
            return R.fail("更新商品信息失败！");
        }
        searchClient.saveOrUpdate(product);

        return R.ok("更新商品信息成功！");
    }

    /**
     * 删除商品信息，
     * 1.购物车、订单有关的不可删除，
     * 2.删除商品信息，图片相关信息，
     * 3.收藏夹，删除商品
     * 3.清除相应的缓存
     * 4.更新es库
     *
     * @param productIdRemoveParam
     * @return
     */
    @CacheEvict(value = "list.product",allEntries = true)
    @Override
    public R adminRemove(ProductIdRemoveParam productIdRemoveParam) {
        //检查购物车是否存在商品，存在不删除
        R cartCheck = cartClient.check(productIdRemoveParam);
        if("004".equals(cartCheck.getCode())){
            log.info("ProductServiceImpl.adminRemove 业务已经完成,结果:{}", "购物车存在商品，不可删除！");
            return cartCheck;
        }
        //检查订单是否存在商品，存在不删除
        R orderCheck = orderClient.check(productIdRemoveParam);
        if("004".equals(orderCheck.getCode())){
            log.info("ProductServiceImpl.adminRemove 业务已经完成,结果:{}", "订单存在商品，不可删除！");
            return orderCheck;
        }

        //删除商品信息和图片性情
        QueryWrapper<Picture> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("product_id",productIdRemoveParam.getProductId());
        int picRows = pictureMapper.delete(queryWrapper);
        log.info("ProductServiceImpl.adminRemove 业务已经完成,结果:图片详情删除{}", picRows);
        int proRows = productMapper.deleteById(productIdRemoveParam);
        log.info("ProductServiceImpl.adminRemove 业务已经完成,结果:商品删除{}",proRows );

        //删除收藏夹中该商品信息
        R r = collectClient.productRemove(productIdRemoveParam);
        //更新es
        searchClient.remove(productIdRemoveParam.getProductId());

        return R.ok("商品数据删除完成！");
    }
}
